<?php
/**
 * Created by jinqiang on 2024/9/24 14:27.
 * Copyright (c) 2024, Your Company. All rights reserved.
 */


namespace App\Http\Services\Soa;


use App\Http\Models\Mysql\SsyAdditionalAmountTable;
use App\Http\Models\Mysql\SsyEmbroiderContractTable;
use App\Http\Models\Mysql\SsyFeishuApprovalBindingTable;
use App\Http\Models\Mysql\SsyFineAmountTable;
use App\Http\Models\Mysql\SsyFlowWfRunTable;
use App\Http\Models\Mysql\SsyPricingContractTable;
use App\Http\Models\Mysql\SsyProcessingFactoryNameTable;
use App\Http\Models\Mysql\SsyProcessingListTable;
use App\Http\Repository\ApprovalRepository;
use App\Http\Repository\EqbRepository;
use App\Http\Repository\FeishuRepository;

class ContractService
{
    private $_prefix = [
        '10010' => 'yxrg',
        '3090235' => 'kz'
    ];

    public function search($param)
    {
        $conn = new SsyPricingContractTable();
        if($param['processing_code'] ?? ""){
            $processingObj = (new SsyProcessingListTable())->where('processing_code', $param['processing_code'])->first();
            if($processingObj->factory_contract_no ?? ""){
                $conn = $conn->where('factory_contract_no', $processingObj->factory_contract_no);
            }else{
                return ['data' => [], 'total' => 0];
            }
        }
        if($param['supplier_id'] ?? ""){
            $conn = $conn->where('supplier_id', $param['supplier_id']);
        }
        if($param['factory_contract_no'] ?? ""){
            $conn = $conn->where('factory_contract_no', 'like', $param['factory_contract_no']."%");
        }
        $subject = array_column(config("scm.subject"), "supplier_id", "brand_code_s");
        if($param['brand_code'] ?? ""){
            $conn = $conn->where('source_factory_groups_id', $subject[$param['brand_code']]);
        }
        if(isset($param['status']) && $param['status'] != ""){
            $conn = $conn->where('status', (Int)$param['status']);
        }
        if(isset($param['b_status']) && $param['b_status'] != ""){
            $conn = $conn->where('b_status', (Int)$param['b_status']);
        }
        if(isset($param['s_status']) && $param['s_status'] != ""){
            $conn = $conn->where('s_status', (Int)$param['s_status']);
        }
        $res = $conn->orderBy('createtime', 'desc')->paginate((Int)$param['limit'])->toArray();
        $factoryContractNo = array_column($res['data'], 'factory_contract_no');
        $field = ['factory_contract_no', 'processing_code', 'type_no', 'type_name', 'jy_number', 'sku_code', 'num', 'unit_price', 'verify_price_number', 'add_date',
            'countnum', 'countprice', 'brand_name'];
        $processingList = (new SsyProcessingListTable())->whereIn('factory_contract_no', $factoryContractNo)->whereIn('source_type', [0, 1])->where('status', 1)
            ->get($field)->toArray();
        $processingMap = [];
        foreach ($processingList as $item){
            $amount = round((Int)$item['num'] * (Double)$item['unit_price'], 2);
            if(isset($processingMap[$item['factory_contract_no']])){
                if(!in_array($item['processing_code'], $processingMap[$item['factory_contract_no']]['processing_code'])){
                    $processingMap[$item['factory_contract_no']]['processing_code'][] = $item['processing_code'];
                    $processingMap[$item['factory_contract_no']]['processing_code_list'][] = $item;
                }
                if(!in_array($item['type_no'], $processingMap[$item['factory_contract_no']]['type_no'])){
                    $processingMap[$item['factory_contract_no']]['type_no'][] = $item['type_no'];
                }
                $processingMap[$item['factory_contract_no']]['contract_amount'] += $amount;
                $processingMap[$item['factory_contract_no']]['total_num'] += (Int)$item['num'];
            }else{
                $processingMap[$item['factory_contract_no']] = [
                    'processing_code' => [$item['processing_code']],
                    'processing_code_list' => [$item],
                    'type_no' => [$item['type_no']],
                    'contract_amount' => $amount,
                    'total_num' => (Int)$item['num'],
                    'brand_name' => $item['brand_name']
                ];
            }
        }
        //审核进度
        $ids = array_column($res['data'], 'id');
        $runMap = [];
        if(!empty($ids)){
            $runList = (new SsyFeishuApprovalBindingTable())->whereIn('data_id', $ids)->where('types', 23)->get(['data_id', 'instance_code'])->toArray();
            $runMap = array_column($runList, 'instance_code', 'data_id');
        }
        foreach ($res['data'] as &$item){
            //额外费用
            $item['additional_amount'] = (new SsyAdditionalAmountTable())->where('factory_contract_no', $item['factory_contract_no'])->where('status', 1)->sum('amount');
            //罚款
            $item['fine_amount'] = (new SsyFineAmountTable())->where('factory_contract_no', $item['factory_contract_no'])->where('status', 1)->sum('amount');
            //合同金额
            if(empty($item['contract_amount'])){
                $item['contract_amount'] = round($processingMap[$item['factory_contract_no']]['contract_amount'] ?? 0, 2);
            }
            //总件数
            $item['total_num'] = $processingMap[$item['factory_contract_no']]['total_num'] ?? 0;
            //加工单
            $item['processing_code'] = $processingMap[$item['factory_contract_no']]['processing_code'] ?? [];
            $item['processing_code_list'] = $processingMap[$item['factory_contract_no']]['processing_code_list'] ?? [];
            //款号
            $item['type_no'] = $processingMap[$item['factory_contract_no']]['type_no'] ?? [];
            //品牌
            $item['brand_name'] = $processingMap[$item['factory_contract_no']]['brand_name'] ?? "";
            //审核进度
            $item['run_id'] = $runMap[$item['id']] ?? "";
        }
        unset($item);
        return ['data' => $res['data'], 'total' => $res['total']];
    }

    public function searchXh($param)
    {
        $conn = new SsyEmbroiderContractTable();
        if($param['processing_code'] ?? ""){
            $conn = $conn->where('processing_code', $param['processing_code']);
        }
        if($param['supplier_id'] ?? ""){
            $conn = $conn->where('supplier_id', $param['supplier_id']);
        }
        if($param['factory_contract_no'] ?? ""){
            $conn = $conn->where('factory_contract_no', 'like', $param['factory_contract_no']."%");
        }
        $subject = array_column(config("scm.subject"), "supplier_id", "brand_code_s");
        if($param['brand_code'] ?? ""){
            $conn = $conn->where('source_factory_groups_id', $subject[$param['brand_code']]);
        }
        $res = $conn->orderBy('createtime', 'desc')->paginate((Int)$param['limit'])->toArray();
        foreach ($res['data'] as &$item){
            //额外费用
            $item['additional_amount'] = (new SsyAdditionalAmountTable())->where('factory_contract_no', $item['factory_contract_no'])->where('status', 1)->sum('amount');
            //罚款
            $item['fine_amount'] = (new SsyFineAmountTable())->where('factory_contract_no', $item['factory_contract_no'])->where('status', 1)->sum('amount');
        }
        unset($item);
        return ['data' => $res['data'], 'total' => $res['total']];
    }

    //重发签署
    public function pushSignature($id)
    {
        $contractObj = (new SsyPricingContractTable())->where('id', $id)->first()->toArray();
        $factoryObj = (new SsyProcessingFactoryNameTable())->where('supplier_id', $contractObj['supplier_id'])->first()->toArray();
        $prefix = $this->_prefix[$contractObj['source_factory_groups_id']] ?? "";
        $signerAccountId = $factoryObj[$prefix."_signer_user_accountid"] ?? "";
        $signerOrgId = $factoryObj[$prefix."_signerorgid"] ?? "";
        if(empty($signerAccountId) || empty($signerOrgId)){
            return ['code' => -1, 'msg' => "E签宝机构id或用户id不能为空"];
        }
        $data = [
            'id_card_no' => $factoryObj['opening_bank_no'],//thirdPartyUserId参数，用户唯一标识，自定义保持唯一即可
            'legal_person' => $factoryObj['legal_person'],//name参数，姓名
            'emergency_contact_phone' => $factoryObj['contact_phone'],//mobile参数，手机号 c5065890f79640e6989a8f6518a81e47
            'factory_name' => $factoryObj['factory_name'],//工厂名
            'fileid' => $contractObj['fileid'],//文件名
            'factory_contract_no' => $contractObj['factory_contract_no'],//文件名
            'signeraccountid' => $signerAccountId,//签署方id--用户
            'signerorgid' => $signerOrgId,//签署方id--机构、公司
        ];
        $isSubject = str_replace("yxrg", "yx", $prefix);
        $res = (new EqbRepository($isSubject))->signflows($data);
        if($res['code'] === 0){
            //修改合同签署状态 签署中
            return (new SsyPricingContractTable())->updateData($id, ['b_status' => 0, 'eqb_flow_id' => $res['data']['flowId']]);
        }
        return ['code' => -1, 'msg' => '发起签署失败, '.$res['message']];
    }

    //合同审批流程
    public function approvalProcess($param)
    {
        //获取审批数据
        $obj = (new SsyPricingContractTable())->where('id', (Int)$param['id'])->first()->toArray();
        $factoryObj = (new SsyProcessingFactoryNameTable())->where('supplier_id', $obj['supplier_id'])->first()->toArray();
        $obj = array_merge($obj, [
            'factory_name' => $factoryObj['factory_name'],//公司名称
            'bank_account' => $factoryObj['bank_account'],//银行账户
            'opening_bank_no' => $factoryObj['opening_bank_no'],//公开户行号
            'bank_of_deposit' => $factoryObj['bank_of_deposit'],//公开行
        ]);
        //获取审批流程
        $user = auth()->guard("api")->user()->toArray();
        $flow = (new FeishuRepository($user['is_subject']))->getFlow($param['run_id']);
        return ['flow' => $flow, 'data' => $obj];
    }

    //查看合同附件
    public function signUrl($id)
    {
        $contractObj = (new SsyPricingContractTable())->where('id', $id)->first()->toArray();
        $factoryObj = (new SsyProcessingFactoryNameTable())->where('supplier_id', $contractObj['source_factory_groups_id'])->first()->toArray();
        $flowId = $contractObj['eqb_flow_id'];
        $prefix = $this->_prefix[$contractObj['source_factory_groups_id']] ?? "";
        $isSubject = str_replace("yxrg", "yx", $prefix);
        $accountId = $factoryObj[$prefix."_signerorgid"] ?? "";
        if(empty($flowId) || empty($accountId)){
            return ['code' => -1, 'msg' => "E签宝机构id或E签宝流程id不能为空"];
        }
        $data = [
            'flowId' => $flowId,
            'accountId' => $accountId,
            'organizeId' => 0,
            'urlType' => "1"
        ];
        $res = (new EqbRepository($isSubject))->signUrl($data);
        if($res['code'] === 0){
            return ['code' => 0, 'data' => $res['data']];
        }
        return ['code' => -1, 'msg' => $res['message'], 'data' => $res];
    }

    //作废合同
    public function cancel($id)
    {
        $contractObj = (new SsyPricingContractTable())->where('id', $id)->first()->toArray();
        if(!in_array($contractObj['status'], [0, 1, 3, 5])){
            return ['code' => -1, 'msg' => '该状态下不能作废'];
        }
        return (new SsyPricingContractTable())->updateData($id, ['status' => 4]);
    }

    //提交合同
    public function submit($id)
    {
        $contractObj = (new SsyPricingContractTable())->where('id', $id)->first()->toArray();
        $prefix = $this->_prefix[$contractObj['source_factory_groups_id']] ?? "";
        $isSubject = str_replace("yxrg", "yx", $prefix);
        if(empty($isSubject)){
            return ['code' => -1, 'msg' => '该工厂暂不能生成合同'];
        }
        $field = ["processing_code","type_no","type_name","sku_code","color_code","size_code","unit_price","num","countnum","countprice",
            "contract_date","order_processor","jy_number"];
        $processingList = (new SsyProcessingListTable())->where('factory_contract_no', $contractObj['factory_contract_no'])->where('status', 1)
            ->whereIn('source_type', [0, 1])->get($field)->toArray();
        list($totalAmount, $totalNum) = [0, 0];
        $detail = [];
        foreach ($processingList as $item){
            if(empty($item['processing_code'])){
                return ['code' => -1, 'msg' => $item['factory_contract_no'].': 加工单号错误，不可生成合同'];
            }
            if(empty($item['jy_number'])){
                return ['code' => -1, 'msg' => $item['processing_code'].': 采购单号为空，不可生成合同！'];
            }
            $totalNum += $item['num'];
            $totalAmount += $item['num'] * $item['unit_price'];
            if(isset($detail[$item['processing_code']])){
                continue;
            }
            $detail[$item['processing_code']] = '[{"id":"processing_code","type":"input","value":"' .$item['processing_code'].'"},{"id":"type_no","type":"input","value":"'
                .$item['type_no'].'"},{"id":"type_name","type":"input","value":"' .$item['type_name'].'"},{"id":"countnum","type":"input","value":"'
                .$item['countnum'].'"},{"id":"price","type":"input","value":"' .$item['unit_price'].'"},{"id":"amount","type":"input","value":"'
                .$item['countprice'].'"}]';
        }
        $save = [
            's_status' => 1,
            'contract_amount' => round($totalAmount, 2),
            'ti_time' => date("Y-m-d")
        ];
        //E签宝生成pdf文件
        if(empty($contractObj['fileid']) || empty($contractObj['contract_url'])){
            $res = (new EqbRepository($isSubject))->createPdf($contractObj, $processingList);
            if($res['code'] !== 0){
                return ['code' => -1, 'msg' => $res['message'] ?? $res['msg'], 'data' => $res];
            }
            $save['fileid'] = $res['data']['fileId'];
            $save['contract_url'] = $res['data']['downloadUrl'];
            $contractObj = array_merge($contractObj, $save);
            //发起部门盖章
            $bumenRes = (new EqbRepository($isSubject))->signflowsBumen($contractObj);
            $save['eqb_flow_id'] = $bumenRes['data']['flowId'] ?? "";
            (new SsyPricingContractTable())->updateData($id, $save);
        }
        //创建绣花合同
        $this->createEmbroideryContract($contractObj);
        //发起飞书审批
        return $this->applyApproval($contractObj, $detail, $totalNum, $totalAmount, $isSubject);
    }

    //发起飞书审批
    public function applyApproval($contractObj, $detail, $totalNum, $totalAmount, $isSubject)
    {
        //发起飞书审批流程
        $detailStr = implode(",", array_values($detail));
        $subjects = array_column(config("scm.subject"), null, 'is_subject');
        $user = auth()->guard("api")->user()->toArray();
        $approvalSubject = in_array($isSubject, ['kz', 'mz', 'qyx']) ? 'kz' : $isSubject;
        $fsUserId = $user[$approvalSubject.'_feishu_user_id'];
        $fsOpenId = $user[$approvalSubject.'_feishu_open_id'];
        $fsApprovalCode = $subjects[$approvalSubject]['contract_approval_code'];
        //$fsApprovalCode = "24E8FBD4-EAC2-45B7-8070-CC7DBA97F0AC";//内部测试
        if(empty($fsApprovalCode)){
            return ['code' => -1, 'msg' => '当前主体未添加该审批流程'];
        }
        $pdfUrl = env("APP_URL")."/api/ext/c/{$contractObj['id']}";
        $subjectLabelMap = ["kz" => "mcn3vkbz-k65m6qitty-0", "yx" => "mcn3vkbz-yqosyldgcu-0", "qyx" => "mcn3vkbz-19tua0d5s8d-0"];
        //品牌字段
        $brandStr = $approvalSubject == "kz" ? '{"id":"is_subject","type":"radioV2","value":"'.$subjectLabelMap[$isSubject].'"},' : "";
        $postData = [
            "approval_code" => $fsApprovalCode,
            "user_id" => $fsUserId,
            "open_id" => $fsOpenId,
            "form" => '['.$brandStr.'{"id":"factory_name","type":"input","value":"' .$contractObj['factory_name'].'"},{"id":"factory_contract_no","type":"input","value":"'
                .$contractObj['factory_contract_no'].'"},{"id":"total_amount","type":"amount","value":"' .$totalAmount.'"},{"id":"total_num","type":"number","value":"'
                .$totalNum.'"},{"id":"contract_date","type":"input","value":"' .$contractObj['contract_date'].'"},{"id":"order_processor","type":"input","value":"'
                .$contractObj['order_processor'].'"},{"id": "detail","type": "fieldList","value": [' .$detailStr.']},{"id":"url","type":"input","value":"'
                .$pdfUrl.'"}]'
        ];
        $res = (new FeishuRepository($approvalSubject))->createApproval($postData);
        if($res['code'] != '0'){
            return ['code' => -1, 'msg' => '创建生产采购合同,失败!'.($res['msg'] ?? ""), 'data' => $res];
        }
        (new SsyPricingContractTable())->updateData($contractObj['id'], ['status' => 1]);
        return (new SsyFeishuApprovalBindingTable())->createData([
            "instance_code" => $res['data']['instance_code'],
            "data_id" => $contractObj['id'],
            "types" => 23,
            "createtime" => date('Y-m-d H:i:s')
        ]);
    }

    //创建绣花合同
    public function createEmbroideryContract($contractObj)
    {
        $field = ["embroidery_factory","processing_code","type_no", "contract_date", "order_processor"];
        $processingList = (new SsyProcessingListTable())->where('factory_contract_no', $contractObj['factory_contract_no'])->whereNotNull('embroidery_factory')
            ->where('embroidery_factory', '<>', '')->groupBy($field)->get($field)->toArray();
        foreach ($processingList as $item) {
            $exist = (new SsyEmbroiderContractTable())->where('processing_code', $item['processing_code'])->where('type_no', $item['type_no'])->exists();
            if(!$exist){
                $factoryName = $item['embroidery_factory'];
                $factoryObj = (new SsyProcessingFactoryNameTable())->where(function ($query) use ($factoryName){
                    $query->where('factory_name', 'like', "%".$factoryName."%")
                        ->orWhere('factory_name_jiancheng', 'like', "%".$factoryName."%");
                })->first();
                $data = [
                    "factory_name" => $item['embroidery_factory'],
                    "factory_contract_no" => "XH".$item['processing_code'].$item['type_no'],
                    "contract_date" => $item['contract_date'],
                    "order_processor"=>$item['order_processor'],
                    "supplier_id" => $factoryObj->supplier_id ?? "",
                    "contract_amount"=>$contractObj['contract_amount'],
                    "processing_code"=>$item['processing_code'],
                    "type_no"=>$item['type_no'],
                    "status"=>2,
                    "factory_contract_no_pricing"=>$contractObj['factory_contract_no'],
                    "source_factory_groups_id" => $contractObj['source_factory_groups_id'],
                    "createtime" => date("Y-m-d H:i:s"),
                ];
                (new SsyEmbroiderContractTable())->createData($data);
            }
        }
    }
}
